using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Windows.Forms;
using Microsoft.Win32;

namespace WIT.Global;

/// <summary>
/// Winform帮助类
/// </summary>
public class WinformHelper
{
	/// <summary>
	/// 开机启动的注册表父级路径
	/// </summary>
	public static readonly RegistryKey REGISTRY_PARENT_KEY = Registry.LocalMachine;

	/// <summary>
	/// 开机启动的注册表子路径
	/// </summary>
	public const string REGISTRY_PATH = "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run";

	/// <summary>
	/// 判断程序是否以管理员身份运行
	/// </summary>
	/// <returns></returns>
	public static bool IsAdministrator()
	{
		return new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
	}

	/// <summary>
	/// 判断某个程序是否已设置开机启动
	/// </summary>
	/// <param name="applicationName">开机启动的程序名</param>  
	/// <returns></returns>
	public static bool IsAutoRun(string applicationName)
	{
		bool result = false;
		RegistryKey registryKey = REGISTRY_PARENT_KEY.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
		try
		{
			string[] valueNames = registryKey.GetValueNames();
			for (int i = 0; i < valueNames.Length; i++)
			{
				if (valueNames[i] == applicationName)
				{
					return true;
				}
			}
			return result;
		}
		catch (Exception ex)
		{
			throw new Exception(MethodBase.GetCurrentMethod().DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>
	/// 判断某个程序是否已设置开机启动
	/// </summary>
	/// <param name="applicationName">开机启动的程序名</param> 
	/// <param name="parentKey">注册表父级路径 （例：Registry.LocalMachine/Registry.CurrentUser）</param> 
	/// <param name="path">注册表子路径 （例：@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"）</param> 
	/// <returns></returns>
	public static bool IsAutoRun(string applicationName, RegistryKey parentKey, string path)
	{
		bool result = false;
		RegistryKey registryKey = parentKey.CreateSubKey(path);
		try
		{
			string[] valueNames = registryKey.GetValueNames();
			for (int i = 0; i < valueNames.Length; i++)
			{
				if (valueNames[i] == applicationName)
				{
					return true;
				}
			}
			return result;
		}
		catch (Exception ex)
		{
			throw new Exception(MethodBase.GetCurrentMethod().DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>  
	/// 设置程序开机启动（修改程序在注册表中的键值  ）
	/// </summary>  
	/// <param name="autoRun">true:开机启动,false:不开机自启</param> 
	/// <param name="applicationName">开机启动的程序名</param> 
	public static void AutoRun(bool autoRun, string applicationName)
	{
		RegistryKey registryKey = REGISTRY_PARENT_KEY.CreateSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run");
		try
		{
			if (autoRun)
			{
				registryKey.SetValue(applicationName, Application.ExecutablePath);
			}
			else
			{
				registryKey.DeleteValue(applicationName, throwOnMissingValue: false);
			}
		}
		catch (Exception ex)
		{
			throw new Exception(MethodBase.GetCurrentMethod().DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>  
	/// 设置程序开机启动（修改程序在注册表中的键值  ）
	/// </summary>  
	/// <param name="isAutoRun">true:开机启动,false:不开机自启</param> 
	/// <param name="applicationName">开机启动的程序名</param> 
	/// <param name="parentKey">注册表父级路径 （例：Registry.LocalMachine/Registry.CurrentUser）</param> 
	/// <param name="path">注册表子路径 （例：@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"）</param> 
	public static void AutoRun(bool isAutoRun, string applicationName, RegistryKey parentKey, string path)
	{
		RegistryKey registryKey = parentKey.CreateSubKey(path);
		try
		{
			if (isAutoRun)
			{
				registryKey.SetValue(applicationName, Application.ExecutablePath);
			}
			else
			{
				registryKey.DeleteValue(applicationName, throwOnMissingValue: false);
			}
		}
		catch (Exception ex)
		{
			throw new Exception(MethodBase.GetCurrentMethod().DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>  
	/// 设置程序开机启动（修改程序在注册表中的键值  ）
	/// </summary>  
	/// <param name="isAutoRun">true:开机启动,false:不开机自启</param> 
	/// <param name="applicationName">开机启动的程序名</param> 
	/// <param name="parentKey">注册表父级路径 （例：Registry.LocalMachine/Registry.CurrentUser）</param> 
	/// <param name="path">注册表子路径 （例：@"SOFTWARE\Microsoft\Windows\CurrentVersion\Run"）</param> 
	/// <param name="executablePath">应用程序的可执行文件的路径，包括可执行文件的名称</param> 
	public static void AutoRun(bool isAutoRun, string applicationName, RegistryKey parentKey, string path, string executablePath)
	{
		RegistryKey registryKey = parentKey.CreateSubKey(path);
		try
		{
			if (isAutoRun)
			{
				registryKey.SetValue(applicationName, executablePath);
			}
			else
			{
				registryKey.DeleteValue(applicationName, throwOnMissingValue: false);
			}
		}
		catch (Exception ex)
		{
			throw new Exception(MethodBase.GetCurrentMethod().DeclaringType.FullName + "发生异常：" + ex.Message + "\r可能需要管理员权限");
		}
		finally
		{
			registryKey.Close();
		}
	}

	/// <summary>
	/// 获取进程专用内存(KB)
	/// </summary>
	/// <param name="processName">进程名，为空时表示当前进程</param>
	/// <returns>KB</returns>
	public static long GetProcessMemory(string processName = "")
	{
		long num = 0L;
		Process process = null;
		try
		{
			if (string.IsNullOrEmpty(processName))
			{
				process = Process.GetCurrentProcess();
			}
			else
			{
				Process[] processesByName = Process.GetProcessesByName(processName);
				if (processesByName.Length == 0)
				{
					throw new Exception("未找到名为" + processName + "的进程");
				}
				if (processesByName.Length > 1)
				{
					throw new Exception($"根据名称{processName}找到{processesByName.Length}个进程");
				}
				process = processesByName[0];
			}
			return (long)(new PerformanceCounter("Process", "Working Set - Private", process.ProcessName).NextValue() / 1024f);
		}
		catch
		{
			return -1L;
		}
		finally
		{
			process?.Dispose();
		}
	}

	/// <summary>
	///
	/// </summary>
	/// <param name="process"></param>
	/// <param name="minSize"></param>
	/// <param name="maxSize"></param>
	/// <returns></returns>
	[DllImport("kernel32.dll")]
	public static extern int SetProcessWorkingSetSize(IntPtr process, int minSize, int maxSize);

	/// <summary>  
	/// 释放内存  
	/// </summary>  
	public static void ClearMemory()
	{
		GC.Collect();
		GC.WaitForPendingFinalizers();
		if (Environment.OSVersion.Platform == PlatformID.Win32NT)
		{
			SetProcessWorkingSetSize(Process.GetCurrentProcess().Handle, -1, -1);
		}
	}

	/// <summary>
	/// 获取计算机名
	/// </summary>
	/// <returns></returns>
	public static string GetHostName()
	{
		return Dns.GetHostName();
	}

	/// <summary>
	/// 获取本机IPv4地址列表
	/// </summary>
	/// <returns></returns>
	public static List<string> GetIPv4()
	{
		List<string> list = new List<string>();
		IPAddress[] hostAddresses = Dns.GetHostAddresses(Dns.GetHostName());
		foreach (IPAddress iPAddress in hostAddresses)
		{
			if (iPAddress.AddressFamily == AddressFamily.InterNetwork)
			{
				list.Add(iPAddress.ToString());
			}
		}
		return list;
	}

	/// <summary>
	/// 获取本机IPv6地址列表
	/// </summary>
	/// <returns></returns>
	public static List<string> GetIPv6()
	{
		List<string> list = new List<string>();
		IPAddress[] hostAddresses = Dns.GetHostAddresses(Dns.GetHostName());
		foreach (IPAddress iPAddress in hostAddresses)
		{
			if (iPAddress.AddressFamily == AddressFamily.InterNetworkV6)
			{
				list.Add(iPAddress.ToString());
			}
		}
		return list;
	}
}
